package com.un.ebs.sys.uitl;


import com.alibaba.druid.pool.DruidDataSource;
import com.un.ebs.sys.domain.DataSource;
import lombok.extern.slf4j.Slf4j;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 数据源连接类
 *
 * @Author lcl
 * @Date 2021/01/20 15:07:22
 */
@Slf4j
public class PoolUtils {

    public static Map<String, DruidDataSource> map = new HashMap<>();

    /**
     * 加载连接池信息
     *
     * @param ds
     * @return
     */
    public static DruidDataSource createPool(DataSource ds) {
        log.info("-----加载连接池信息-----");
        //数据源配置
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setUrl(ds.getIpAddr());
        //druidDataSource.setDriverClassName(ds.getDriveName()); //这个可以缺省的，会根据url自动识别
        druidDataSource.setUsername(ds.getUserName());
        druidDataSource.setPassword(ds.getPassword());

        //下面都是可选的配置
        druidDataSource.setInitialSize(10);  //初始连接数，默认0
        druidDataSource.setMaxActive(20);  //最大连接数，默认8
        druidDataSource.setMinIdle(10);  //最小闲置数
        druidDataSource.setMaxWait(2000);  //获取连接的最大等待时间，单位毫秒
        druidDataSource.setConnectionErrorRetryAttempts(1);//失败后重连次数为1
        druidDataSource.setBreakAfterAcquireFailure(true);
        return druidDataSource;
    }


    /**
     * 返回连接对象
     *
     * @param ds
     * @return
     */
    public static Connection getConnection(DataSource ds) {
        String keySource = ds.getName();
        Connection connection = null;
        DruidDataSource pool;
        try {
            //判断该数据源是否创建连接池
            if (map.containsKey(keySource)) {
                //存在
                log.info("从连接池里面拿！");
                pool = map.get(keySource);
                connection = pool.getConnection();
            } else {
                //不存在
                log.info("不存在，新建连接池！");
                pool = createPool(ds);
                connection = pool.getConnection();
                map.put(ds.getName(), pool);
            }
        } catch (SQLException e) {
            throw new Exception(String.format("数据库错误：code：%s，message：%s", e.getErrorCode(), e.getMessage()));
        } finally {
            return connection;
        }
    }

    /**
     * 执行sql语句
     *
     * @param sql
     * @param ds
     * @return
     * @throws SQLException
     */
    public static boolean executeSql(String sql, DataSource ds) {
        try {
            Connection con = getConnection(ds);
            Statement stmt = null;
            boolean flag = false;
            try {
                stmt = con.createStatement();
                int a = stmt.executeUpdate(sql);
                if (0 == a) {
                    flag = true;
                }
                return flag;
            } catch (SQLException e) {
                throw new RuntimeException(e.getMessage());
            } finally {
                con.close();
                stmt.close();
            }
        } catch (Exception e) {
            throw new RuntimeException("数据库异常：" + e.getMessage());
        }
    }

    /**
     * 判断表，外键是否存在
     *
     * @param sql
     * @param ds
     * @return
     * @throws SQLException
     */
    public static boolean isExistSql(String sql, DataSource ds) {
        try {
            Connection con = getConnection(ds);
            Statement stmt = null;
            boolean flag = false;
            try {
                stmt = con.createStatement();
                ResultSet rs = stmt.executeQuery(sql);
                if (rs.next()) {
                    int count = Integer.parseInt(rs.getString("count"));
                    if (count >= 1) {
                        flag = true;
                    }
                }
                return flag;
            } catch (SQLException e) {
                throw new RuntimeException(e.getMessage());
            } finally {
                con.close();
                stmt.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("数据库异常：" + e.getMessage());
        }
    }

    /**
     * 执行多条sql语句
     *
     * @param sql
     * @param ds
     * @return
     * @throws SQLException
     */
    public static boolean executeSqlList(List<String> sql, DataSource ds) {
        try {
            Connection con = PoolUtils.getConnection(ds);
            con.setAutoCommit(false);
            Statement stmt = con.createStatement();
            boolean flag = false;
            try {
                for (String str : sql) {
                    int a = stmt.executeUpdate(str);
                    if (a == 0) {
                        flag = true;
                    }
                }
                con.commit();
                return flag;
            } catch (SQLException e) {
                //回滚
                con.rollback();
                throw new RuntimeException(e.getMessage());
            } finally {
                con.close();
                stmt.close();
                log.info(ds.getName() + ":连接已关闭.");
            }
        } catch (Exception e) {
            throw new RuntimeException("数据库异常：" + e.getMessage());
        }
    }
}
